/*
 * Copyright (C), 2002-2017, 南京苏宁软件技术有限公司
 * FileName: ExchangeOrderCouponListQueryServiceImpl.java
 * Author:   10070706
 * Date:     2017年5月3日 上午11:23:33
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.exchange;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.suning.api.rsf.service.ApiRemoteMapService;
import com.suning.ebuy.spes.nonshoppingexecute.dto.freecoupon.FreeCouponReceiveInputDto;
import com.suning.ebuy.spes.nonshoppingexecute.dto.freecoupon.FreeCouponReceiveOutputDto;
import com.suning.ebuy.spes.nonshoppingexecute.service.FreeCouponReceiveReqService;
import com.suning.rsc.RscException;
import com.suning.rsc.dto.responsedto.MbfResponse;
import com.suning.rsc.httpservice.annotation.EsbEIHttpWired;
import com.suning.rsf.consumer.ServiceAgent;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.rsf.spring.Reference;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.ExchangeConstants;
import com.suning.sawp.constants.PromSysConstants;
import com.suning.sawp.constants.PromotionConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.esb.AsopProductInfoReq;
import com.suning.sawp.dto.esb.CouponRuleQueryReq;
import com.suning.sawp.dto.esb.LocateMemberInfo;
import com.suning.sawp.dto.esb.QryActDetailReq;
import com.suning.sawp.dto.esb.QryActDetailRsp;
import com.suning.sawp.dto.esb.QryActDetailRsp.ActivityDetail;
import com.suning.sawp.dto.exchange.ExchangeCouponDetail;
import com.suning.sawp.dto.exchange.ExchangeCouponResponseDto;
import com.suning.sawp.dto.exchange.ExchangeOrderCouponRecord;
import com.suning.sawp.dto.exchange.ExchangeOrderDetail;
import com.suning.sawp.dto.exchange.ExchangeOrderResponseDto;
import com.suning.sawp.dto.exchange.QueryCouponDetailInfoFromSPESEsbDto;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.intf.dao.exchange.ExchangeActivityDao;
import com.suning.sawp.intf.dao.exchange.ExchangeCouponRecordDao;
import com.suning.sawp.intf.esb.CouponRuleQueryEsbService;
import com.suning.sawp.intf.esb.ExchangeProductInfoEsbService;
import com.suning.sawp.intf.esb.MemberInfoService;
import com.suning.sawp.intf.esb.PromotionSysService;
import com.suning.sawp.intf.exchange.ExchangeOrderCouponListQueryService;
import com.suning.sawp.intf.promotion.CityTransService;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.po.exchange.ExchangeActivity;
import com.suning.sawp.service.util.ConfigUtil;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.RedisCacheUtils;
import com.suning.sawp.service.util.StringParamUtils;
import com.suning.sawp.service.util.XmlUtils;
import com.suning.sawp.vo.exchange.ActivityInfoVo;
import com.suning.sawp.vo.exchange.ActivityRuleVo;
import com.suning.sawp.vo.exchange.ExchangeOrderVo;

/**
 * 〈以旧换新订单列表和券列表查询服务实现〉<br>
 *
 * @author 10070706
 */
@Service
public class ExchangeOrderCouponListQueryServiceImpl implements ExchangeOrderCouponListQueryService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExchangeOrderCouponListQueryServiceImpl.class);

    @Autowired
    private RedisCacheUtils redisClient;

    private ExchangeProductInfoEsbService exchangeProductInfoEsbService;

    @EsbEIHttpWired
    public void setExchangeProductInfoEsbService(ExchangeProductInfoEsbService exchangeProductInfoEsbService) {
        this.exchangeProductInfoEsbService = exchangeProductInfoEsbService;
    }

    // 售后服务系统 获取统一调用接口
    private ServiceAgent agent = ServiceLocator.getServiceAgent(ApiRemoteMapService.class.getName(),
            "ASOM-queryRecyclingOrderProfile", false);

    @Autowired
    private ExchangeCouponRecordDao exchangeCouponRecordDao;

    @Autowired
    private StoreManService storeManService;

    private PromotionSysService promotionSysService;

    @EsbEIHttpWired
    public void setPromotionSysService(PromotionSysService promotionSysService) {
        this.promotionSysService = promotionSysService;
    }

    @Autowired
    private ExchangeActivityDao exchangeActivityDao;

    @Reference(contract = FreeCouponReceiveReqService.class, implCode = "freeCouponReceive")
    private FreeCouponReceiveReqService freeCouponReceiveReqService;

    @Autowired
    private MemberInfoService memberInfoService;

    private CouponRuleQueryEsbService couponRuleQueryEsbService;

    @EsbEIHttpWired
    public void setCouponRuleQueryEsbService(CouponRuleQueryEsbService couponRuleQueryEsbService) {
        this.couponRuleQueryEsbService = couponRuleQueryEsbService;
    }

    @Autowired
    private CityTransService cityTransService;

    @SuppressWarnings("unchecked")
    @Override
    public ReturnMsg<ExchangeOrderResponseDto> queryOrderList(String mobileNo, Integer pageNo) {
        // 最终返回结果
        ReturnMsg<ExchangeOrderResponseDto> ret = new ReturnMsg<ExchangeOrderResponseDto>();
        ExchangeOrderResponseDto resp = new ExchangeOrderResponseDto();
        resp.setMobileNo(StringParamUtils.desensitizeMobilePhone(mobileNo));

        List<ExchangeOrderDetail> orderList = new ArrayList<ExchangeOrderDetail>();
        resp.setOrderList(orderList);

        Map<String, Object> param = new HashMap<String, Object>();
        param.put("msgSrc", "SN");
        param.put("memberPhone", mobileNo);
        param.put("currentPageNumber", pageNo);
        param.put("perPageRecordNumber", ExchangeConstants.PAGE_SIZE);

        String errMsg;
        // 获取统一调用接口
        Map<String, Object> rlt = (Map<String, Object>) agent.invoke("execute", new Object[] { param },
                new Class[] { Map.class });
        if (!StringUtils.equals(ExchangeConstants.ASOM_ERR_CODR_OF_SUCCESS, (String) rlt.get("errorCode"))) {
            errMsg = (String) rlt.get("errorMassage");

            // 包装下查询记录为空的异常，便于客户端处理
            if (StringUtils.equals("查询记录为空", errMsg)) {
                resp.setCustName("顾客");
                ret.setData(resp);
                return ret;
            } else {
                ret.setError(ErrorCodeConstants.EXCHANGE_OUT_SYS_ERR, new Object[] { errMsg });
                return ret;
            }
        }
        if (null == rlt.get("totalRecord")
                || StringUtils.equals(StringUtils.EMPTY, String.valueOf(rlt.get("totalRecord")))
                || Integer.parseInt(String.valueOf(rlt.get("totalRecord"))) <= 0) {
            resp.setCustName("顾客");
            ret.setData(resp);
            return ret;
        }

        ExchangeOrderDetail order;
        List<Map<String, Object>> params = (List<Map<String, Object>>) rlt.get("data");

        String orderStatus;
        String orderStatusDesc;
        String body;
        AsopProductInfoReq req;
        Document doc;
        String cmmdtyCode;

        // 商品编码查询不到商品信息时，都默认是空
        String cmmdtyName = StringUtils.EMPTY;
        String cmmdtyPic = StringUtils.EMPTY;
        String cateCode = StringUtils.EMPTY;
        String custName = null;

        List<ExchangeOrderCouponRecord> records;
        String createTime;

        ExchangeOrderVo orderVo;
        for (Map<String, Object> param1 : params) {
            if (StringUtils.isEmpty(custName)) {
                custName = (String) param1.get("memberName");
            }
            order = new ExchangeOrderDetail();
            order.setOrderNo((String) param1.get("orderNo"));
            createTime = (String) param1.get("orderDttm");
            createTime = StringUtils.isEmpty(createTime)
                    ? DateUtils.getDateStrByFormat(new Date(), DateUtils.ACCURATE_MINUTES_PATTERN)
                    : StringUtils.substring(createTime, 0, 16);
            order.setCreateTime(createTime);
            cmmdtyCode = (String) param1.get("itemCode");
            order.setCmmdtyCode(cmmdtyCode);
            // 处理下状态描述，万一订单无状态，则直接记为空，用空取匹配发券规则（一定匹配不上，则不发券）
            if (null == param1.get("queryOrderItemStatus")
                    || StringUtils.equals(StringUtils.EMPTY, (String) param1.get("queryOrderItemStatus"))) {
                orderStatus = StringUtils.EMPTY;
            } else {
                orderStatus = (String) param1.get("queryOrderItemStatus");
            }
            orderStatusDesc = ExchangeConstants.OrderStatus.getMsg(orderStatus);
            order.setOrderStatus(orderStatus);
            order.setOrderStatusDesc(orderStatusDesc);
            order.setEvaluatePrice((String) param1.get("evaluatePrice"));
            order.setCmmdtyNum((String) param1.get("saleCount"));
            req = new AsopProductInfoReq(cmmdtyCode);
            body = "<MbfBody>" + exchangeProductInfoEsbService.queryExchangeProductInfo(req).getOutput().getMbfBodyXml()
                    + "</MbfBody>";
            try {
                doc = XmlUtils.getW3CDom(body);
                String totalCount = XmlUtils.getValueByXpath(doc, "/MbfBody/totalCount");
                if (StringUtils.equals(ExchangeConstants.TOTAL_COUNT_ZERO, totalCount)) {
                    LOGGER.info("商品编码:{},查询商品信息返回空!", cmmdtyCode);
                } else {
                    cmmdtyName = XmlUtils.getValueByXpath(doc, "/MbfBody/datas/data/itemInfo/itemName");
                    cmmdtyPic = XmlUtils.getValueByXpath(doc, "MbfBody/datas/data/itemInfo/itemPic");
                    cateCode = XmlUtils.getValueByXpath(doc, "/MbfBody/datas/data/itemInfo/brandCode");
                }
            } catch (Exception e) {
                LOGGER.error("商品编码:{},查询商品详情信息异常:", cmmdtyCode, e);
            }
            order.setCmmdtyName(cmmdtyName);
            order.setCmmdtyPic(cmmdtyPic);
            order.setCateCode(cateCode);

            orderVo = getExchangeOrderVo(order, (String) param1.get("memberCard"));
            // 缓存订单号和订单详情
            redisClient.set(String.format(CacheKeyConstants.EXCHANGE_ORDER_INFO, order.getOrderNo()),
                    new Gson().toJson(orderVo));
            redisClient.expire(String.format(CacheKeyConstants.EXCHANGE_ORDER_INFO, order.getOrderNo()),
                    DateUtils.end2TodaySeconds());

            // 缓存手机号和订单号列表的关系
            redisClient.sadd(String.format(CacheKeyConstants.EXCHANGE_MOBILE_ORDER, mobileNo), order.getOrderNo());
            redisClient.expire(String.format(CacheKeyConstants.EXCHANGE_MOBILE_ORDER, mobileNo),
                    DateUtils.end2TodaySeconds());

            records = exchangeCouponRecordDao.queryOrderCoupon((String) param1.get("orderNo"));
            order.setCouponList(records);
            orderList.add(order);
        }

        resp.setCustName(StringParamUtils.clearUserName(custName));
        ret.setData(resp);
        return ret;
    }

    /**
     * 
     * 功能描述: 内部订单对象<br>
     * 
     * @param order
     * @param custNum
     * @return
     */
    private ExchangeOrderVo getExchangeOrderVo(ExchangeOrderDetail order, String custNum) {
        ExchangeOrderVo od = new ExchangeOrderVo();
        od.setOrderNo(order.getOrderNo());
        od.setCreateTime(order.getCreateTime());
        od.setOrderStatus(order.getOrderStatus());
        od.setOrderStatusDesc(order.getOrderStatusDesc());
        od.setCmmdtyCode(order.getCmmdtyCode());
        od.setCmmdtyPic(order.getCmmdtyPic());
        od.setCmmdtyName(order.getCmmdtyName());
        od.setEvaluatePrice(order.getEvaluatePrice());
        od.setCmmdtyNum(order.getCmmdtyNum());
        od.setCateCode(order.getCateCode());
        od.setCustNum(custNum);
        return od;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ReturnMsg<ExchangeCouponResponseDto> queryCouponList(String orderNo, String employeeId) {
        ReturnMsg<ExchangeCouponResponseDto> ret = new ReturnMsg<ExchangeCouponResponseDto>();
        ExchangeCouponResponseDto resp = new ExchangeCouponResponseDto();
        List<ExchangeCouponDetail> couponList = new ArrayList<ExchangeCouponDetail>();
        resp.setCouponList(couponList);

        // 根据员工工号取员工信息
        StoreManDto storeMan = storeManService.queryStoreManAttachInfo(employeeId);
        String storeCode = storeMan.getStoreCode();
        if (StringUtils.isEmpty(storeCode)) {
            ret.setError(ErrorCodeConstants.EXCHANGE_NO_STORE);
            return ret;
        }
        String cityId = StringUtils.leftPad(cityTransService.getMdmCityCodeFromPosCityCode(storeMan.getCityCode()),
                ExchangeConstants.COUPON_CENTER_CITY_LEN, "0");

        QryActDetailReq req = new QryActDetailReq();

        req.setBonusTrigerId(ExchangeConstants.BONUS_TRIGER_ID);
        req.setActivityInitiator(PromSysConstants.ACTIVITY_INITIATOR_PLAT);

        QryActDetailRsp result;
        List<ActivityDetail> allActivity = null;
        MbfResponse response;
        try {
            // 线下传门店编码
            req.setEntityStoreID(storeCode);
            // 先查37
            req.setChannelId(PromSysConstants.OFFLINE_CHANNEL_ID);
            response = promotionSysService.queryActivityDetail(req);
            result = (QryActDetailRsp) response.getOutput().getMbfBody(QryActDetailRsp.class);
            if (!StringUtils.equals(ExchangeConstants.SEND_COUPON_RESULT_FALE, result.getRequestResult())) {
                for (ActivityDetail detail : result.getActivityList()) {
                    // 缓存活动id和活动名称
                    redisClient.set(String.format(CacheKeyConstants.EXCHANGE_ACTIVITY_INFO, detail.getActivityId()),
                            new Gson().toJson(new ActivityInfoVo(detail.getActivityId(), detail.getActivityName(),
                                    PromSysConstants.OFFLINE_CHANNEL_ID)));
                    redisClient.expire(String.format(CacheKeyConstants.EXCHANGE_ORDER_INFO, detail.getActivityId()),
                            DateUtils.end2TodaySeconds());
                }
                allActivity = result.getActivityList();
            }

            // 再查38
            req.setChannelId(PromSysConstants.TERMINAL_ID_MARKET);
            response = promotionSysService.queryActivityDetail(req);
            result = (QryActDetailRsp) response.getOutput().getMbfBody(QryActDetailRsp.class);
            if (!StringUtils.equals(ExchangeConstants.SEND_COUPON_RESULT_FALE, result.getRequestResult())) {
                for (ActivityDetail detail : result.getActivityList()) {
                    // 缓存活动id和活动名称
                    redisClient.set(String.format(CacheKeyConstants.EXCHANGE_ACTIVITY_INFO, detail.getActivityId()),
                            new Gson().toJson(new ActivityInfoVo(detail.getActivityId(), detail.getActivityName(),
                                    PromSysConstants.TERMINAL_ID_MARKET)));
                    redisClient.expire(String.format(CacheKeyConstants.EXCHANGE_ORDER_INFO, detail.getActivityId()),
                            DateUtils.end2TodaySeconds());
                }
                allActivity = ListUtils.sum(allActivity, result.getActivityList());
            }

            // 线上传城市编码
            req.setEntityStoreID(null);
            req.setCityId(cityId);
            // 最后查31
            req.setChannelId(PromSysConstants.ONLINE_CHANNEL_ID);
            response = promotionSysService.queryActivityDetail(req);
            result = (QryActDetailRsp) response.getOutput().getMbfBody(QryActDetailRsp.class);
            if (!StringUtils.equals(ExchangeConstants.SEND_COUPON_RESULT_FALE, result.getRequestResult())) {
                for (ActivityDetail detail : result.getActivityList()) {
                    // 缓存活动id和活动名称
                    redisClient.set(String.format(CacheKeyConstants.EXCHANGE_ACTIVITY_INFO, detail.getActivityId()),
                            new Gson().toJson(new ActivityInfoVo(detail.getActivityId(), detail.getActivityName(),
                                    PromSysConstants.ONLINE_CHANNEL_ID)));
                    redisClient.expire(String.format(CacheKeyConstants.EXCHANGE_ORDER_INFO, detail.getActivityId()),
                            DateUtils.end2TodaySeconds());
                }
                allActivity = ListUtils.sum(allActivity, result.getActivityList());
            }

            if (CollectionUtils.isEmpty(allActivity)) {
                ret.setData(resp);
                return ret;
            }

        } catch (RscException e) {
            LOGGER.error("查询可发券列表，调用活动名称与编码查询接口异常:", e);
            ret.setError(ErrorCodeConstants.ERR_0002);
            return ret;
        }

        // 从redis缓存中取出订单信息
        String orderStr = redisClient.get(String.format(CacheKeyConstants.EXCHANGE_ORDER_INFO, orderNo));
        if (StringUtils.isEmpty(orderStr)) {
            ret.setError(ErrorCodeConstants.EXCHANGE_NO_ORDER);
            return ret;
        }
        ExchangeOrderVo order = new Gson().fromJson(orderStr, new TypeToken<ExchangeOrderVo>() {
        }.getType());

        // 通过接口拉回来的员工对应门店所有可以参加的活动id 集合
        List<String> activityIds = Lists.transform(allActivity, new Function<ActivityDetail, String>() {
            @Override
            public String apply(ActivityDetail input) {
                return input.getActivityId();
            }
        });

        // 判断后台配置哪些活动id
        List<String> configActivityIdList = exchangeActivityDao.queryExchangeActivity(activityIds);

        // 得到未配置的活动，作为直接可以参加的活动
        List<ActivityDetail> joinActivity = getNotNeedHandleActivity(allActivity, configActivityIdList);
        allActivity.removeAll(joinActivity);
        // 这些是需要判断后台配置情况的活动
        List<ActivityDetail> configActivity = allActivity;
        // 过滤后可以参加的活动
        List<ActivityDetail> filterActivity = getCanJoinActivity(configActivity, order);
        // 汇总，得到所有可以参加的活动
        joinActivity.addAll(filterActivity);

        LocateMemberInfo memberInfo = memberInfoService
                .locateMemberByMobileNo(ConfigConstants.INNER_COUPON_DEFAULT_MOBILE);
        String memberId = memberInfo.getCustNum();

        FreeCouponReceiveInputDto couponInput;
        FreeCouponReceiveOutputDto couponOutput;
        CouponRuleQueryReq reqRule;
        ExchangeCouponDetail couponDetail;
        QueryCouponDetailInfoFromSPESEsbDto couponRuleDetail;
        ActivityInfoVo acticityInfo;
        for (ActivityDetail activity : joinActivity) {
            couponInput = new FreeCouponReceiveInputDto();
            couponInput.setCaller(ExchangeConstants.CALLER);
            couponInput.setBonusTrigerId(ExchangeConstants.BONUS_TRIGER_ID);
            couponInput.setOperateType(ExchangeConstants.OP_TYPE_QUERY);
            couponInput.setActivityId(activity.getActivityId());
            couponInput.setActivitySecretKey(activity.getActivitySecretKey());
            couponInput.setMemberId(memberId);

            // 终端每个活动都可能不一样
            acticityInfo = new Gson().fromJson(
                    redisClient.get(String.format(CacheKeyConstants.EXCHANGE_ACTIVITY_INFO, activity.getActivityId())),
                    new TypeToken<ActivityInfoVo>() {
                    }.getType());
            couponInput.setTerminalId(acticityInfo.getChannelId());

            couponInput.setCityId(cityId);
            couponInput.setStoreCode(storeCode);
            couponInput.setCompanyCode(storeMan.getBranchCode());
            couponInput.setPayDate(DateUtils.getDateStrByFormat(
                    DateUtils.getDateByStr(order.getCreateTime(), DateUtils.ACCURATE_MINUTES_PATTERN),
                    DateUtils.DEFAULT_TIME_PATTERN));
            couponInput.setChannelId(ExchangeConstants.CHANNEL_ID);

            couponOutput = freeCouponReceiveReqService.receiveFreeCoupon(couponInput);
            if (!StringUtils.equals(ExchangeConstants.SEND_COUPON_RESULT_FALE, couponOutput.getResultFlag())) {
                couponDetail = new ExchangeCouponDetail();

                // 组织前台接口数据
                couponDetail.setActivityId(activity.getActivityId());
                couponDetail.setActivitySecretKey(activity.getActivitySecretKey());
                couponDetail.setCouponType(ExchangeConstants.CouponType.getName(couponOutput.getCouponType()));
                couponDetail.setCouponAmount(couponOutput.getCouponAmount());

                reqRule = new CouponRuleQueryReq();
                reqRule.setSourceSystem(PromotionConstants.SYS_CODE_SNSAWP);
                reqRule.setCouponRulesId(couponOutput.getCouponRuleCode());
                reqRule.setPartScopeQuantityLimitNumber(ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_PATH,
                        ConfigConstants.PRO_COUPON_RULE_QUERY_LIMIT, ConfigConstants.DEFAULT_COUPON_RULE_LIMIT));
                couponRuleDetail = (QueryCouponDetailInfoFromSPESEsbDto) couponRuleQueryEsbService
                        .queryCouponRule(reqRule).getOutput().getMbfBody(QueryCouponDetailInfoFromSPESEsbDto.class);
                if (!StringUtils.equals(ExchangeConstants.SEND_COUPON_RESULT_FALE, couponOutput.getResultFlag())) {
                    couponDetail.setCouponRulesShowMsg(couponRuleDetail.getCouponRulesShowMsg());
                    couponDetail.setRewardsPreferential(couponRuleDetail.getRewardsPreferential());
                    couponList.add(couponDetail);

                    // 缓存订单号和活动列表的关系
                    redisClient.sadd(String.format(CacheKeyConstants.EXCHANGE_ORDER_ACTIVITY, orderNo),
                            activity.getActivityId());
                    redisClient.expire(String.format(CacheKeyConstants.EXCHANGE_ORDER_ACTIVITY, orderNo),
                            DateUtils.end2TodaySeconds());
                }
            }
        }

        resp.setCouponList(couponList);
        ret.setData(resp);
        return ret;
    }

    /**
     * 
     * 功能描述: 拼接活动id<br>
     * 
     * @param list
     * @return
     */
    // private String allActivityIds(List<ActivityDetail> list) {
    // StringBuilder sb = new StringBuilder();
    // for (ActivityDetail activity : list) {
    // sb.append("'").append(activity.getActivityId()).append("',");
    // }
    // return sb.substring(0, sb.length() - 1);
    // }

    /**
     * 
     * 功能描述: 找出不需要判断配置情况的活动<br>
     * 
     * @param allActivity
     * @param configActivityList
     * @return
     */
    public List<ActivityDetail> getNotNeedHandleActivity(List<ActivityDetail> allActivity,
            List<String> configActivityIdList) {
        List<ActivityDetail> result = new ArrayList<ActivityDetail>();

        for (ActivityDetail per : allActivity) {
            boolean flag = false;
            for (String activityId : configActivityIdList) {
                if (StringUtils.equals(per.getActivityId(), activityId)) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                result.add(per);
            }
        }
        return result;
    }

    /**
     * 
     * 功能描述: 后台配置的规则和订单当前的属性匹配，获取可以参加的活动集合<br>
     * 
     * @param configActivity
     * @param order
     * @return
     */
    @Override
    public List<ActivityDetail> getCanJoinActivity(List<ActivityDetail> configActivity, ExchangeOrderVo order) {
        List<ActivityDetail> result = new ArrayList<ActivityDetail>();
        if (CollectionUtils.isEmpty(configActivity)) {
            return result;
        }

        List<String> activityIds = Lists.transform(configActivity, new Function<ActivityDetail, String>() {
            @Override
            public String apply(ActivityDetail input) {
                return input.getActivityId();
            }
        });

        // 最终不可以参加活动的id集合
        Set<String> activityIdList = new HashSet<String>();

        // 1、先匹配订单时间(由于维度不一样，需要分开匹配)
        List<ExchangeActivity> ruleTime = exchangeActivityDao.queryExchangeActivityInfo(activityIds);
        Date orderStartTime;
        Date orderEndTime;
        Date orderCreateTime = DateUtils.getDateByStr(order.getCreateTime(), DateUtils.ACCURATE_MINUTES_PATTERN);
        for (ExchangeActivity activity : ruleTime) {
            // 为false 默认标记可以参加，为true表示触发规则控制，不能参加
            boolean flag = false;

            // 校验订单时间
            orderStartTime = StringUtils.isEmpty(activity.getOrderStartTime()) ? null
                    : DateUtils.getDateByStr(activity.getOrderStartTime(), DateUtils.DEFAULT_TIME_PATTERN);
            orderEndTime = StringUtils.isEmpty(activity.getOrderEndTime()) ? null
                    : DateUtils.getDateByStr(activity.getOrderEndTime(), DateUtils.DEFAULT_TIME_PATTERN);
            if (null != orderStartTime) {
                if (orderCreateTime.before(orderStartTime)) {
                    flag = true;
                }
            }

            if (null != orderEndTime) {
                if (orderCreateTime.after(orderEndTime)) {
                    flag = true;
                }
            }

            // true表示触发规则控制，不可以发券
            if (flag) {
                activityIdList.add(activity.getActivityId());
            }
        }

        // 1、再匹配订单状态和品类
        List<ActivityRuleVo> rules = exchangeActivityDao.queryActivityRule(activityIds);
        Map<String, List<ActivityRuleVo>> ruleMap = buildByActivityId(rules);
        String orderStatus = order.getOrderStatus();
        String orderCate = order.getCateCode();
        List<ActivityRuleVo> orderStatusRules;
        List<ActivityRuleVo> cateRules;

        for (Map.Entry<String, List<ActivityRuleVo>> per : ruleMap.entrySet()) {
            // 为false 默认标记可以参加，为true表示触发规则控制，不能参加
            boolean flag = false;
            boolean orderStatusFlag = false;
            boolean cateFlag = false;

            // 校验订单状态
            orderStatusRules = getActivityRuleByConfigType(per.getValue(), ExchangeConstants.RULE_ORDER_STATUS);
            if (!CollectionUtils.isEmpty(orderStatusRules)) {
                for (ActivityRuleVo rule1 : orderStatusRules) {
                    if (StringUtils.equals(orderStatus, rule1.getConfigValue())) {
                        orderStatusFlag = true;
                    }
                }
                if (!orderStatusFlag) {
                    flag = true;
                }
            }

            // 校验品类
            cateRules = getActivityRuleByConfigType(per.getValue(), ExchangeConstants.RULE_CATE);
            if (!CollectionUtils.isEmpty(cateRules)) {
                for (ActivityRuleVo rule2 : cateRules) {
                    if (StringUtils.equals(orderCate, rule2.getConfigValue())) {
                        cateFlag = true;
                    }
                }
                if (!cateFlag) {
                    flag = true;
                }
            }

            // true表示触发规则控制，不可以发券
            if (flag) {
                activityIdList.add(per.getKey());
            }
        }

        for (ActivityDetail detail : configActivity) {
            boolean cantSendCoupon = true;
            for (String activityId : activityIdList) {
                if (StringUtils.equals(detail.getActivityId(), activityId)) {
                    cantSendCoupon = false;
                    break;
                }
            }
            if (cantSendCoupon) {
                result.add(detail);
            }
        }
        return result;
    }

    /**
     * 
     * 功能描述: 按活动id归集活动规则<br>
     * 
     * @param rules
     * @return
     */
    private Map<String, List<ActivityRuleVo>> buildByActivityId(List<ActivityRuleVo> rules) {
        Map<String, List<ActivityRuleVo>> map = new HashMap<String, List<ActivityRuleVo>>();
        for (ActivityRuleVo rule : rules) {
            if (map.containsKey(rule.getActivityId())) {
                map.get(rule.getActivityId()).add(rule);
            } else {
                List<ActivityRuleVo> temp = new ArrayList<ActivityRuleVo>();
                temp.add(rule);
                map.put(rule.getActivityId(), temp);
            }
        }

        return map;
    }

    /**
     * 
     * 功能描述: 按类型匹配配置规则<br>
     * 
     * @param rules
     * @param configType
     * @return
     */
    private List<ActivityRuleVo> getActivityRuleByConfigType(List<ActivityRuleVo> rules, int configType) {
        List<ActivityRuleVo> result = new ArrayList<ActivityRuleVo>();
        for (ActivityRuleVo rule : rules) {
            if (configType == rule.getConfigType().intValue()) {
                result.add(rule);
            }
        }
        return result;
    }
}
